package com.DJRelayAndroidClient_ACE.djrelay_androidclient;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import com.DJRelayAndroidClient_ACE.djrelay_androidclient.MainActivity.requestType;

import android.app.Activity;
import android.util.Log;

public class HttpHelper {
	
	public String randSongID;
	public JSONObject jsonData;
//	public enum accessMode {POST, GET, POSTGET};
	
	private int mCallBackActivity;
	
	public HttpHelper (int callingActivity) {
		mCallBackActivity = callingActivity;
	}
	
	// TODO - This should have option to just trigger random song selection only w/o updating user selected song
	public void httpPostGet(final requestType requestType, final String serverAddress, final String songBufferAddress, 
							final String ... paramNamesValues) {
		
		new Thread (new Runnable() {
			public void run() {
				InputStream is = null;
				String result = null;

				try {
					String mIP = getLocalIpAddress();
					Log.i("myApp", "IP Address = " + mIP);

					ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
					nameValuePairs.add(new BasicNameValuePair("ip", mIP));
					if (paramNamesValues != null) {
						for (int i=0; i<paramNamesValues.length-1; i=i+2) {
							String paramName = paramNamesValues[i];
							String paramValue = paramNamesValues[i+1];  
							nameValuePairs.add(new BasicNameValuePair(paramName, paramValue));
						}
					}

					// http POST
					HttpClient httpclient = new DefaultHttpClient();
					HttpPost httppost = new HttpPost(serverAddress);					// TODO - Needs to be updated to domain name when set up,
					httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));		// amongst many other things :)
					HttpResponse response = httpclient.execute(httppost);
					HttpEntity entity = response.getEntity();

					is = entity.getContent();
					BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
					StringBuilder sb = new StringBuilder();

					String line = null;
					while ((line = reader.readLine()) != null) {
						sb.append(line + "\n");
					}

					is.close();        			 
					result=sb.toString();
					Log.i("myApp", "Server Response = " + result);

				} catch (Exception e) {											
					Log.e("myApp", "HTTP Connection ERROR! = " + e.toString() + ": " + e.getMessage());
					e.printStackTrace();
					// TODO - Pop notification to user indicating server is down
					if (mCallBackActivity == MainActivity.LOGIN_ACTIVITY) 
						LoginActivity.mHandler.sendEmptyMessage(0);
					else
						MainActivity.mHandler.sendEmptyMessage(0);
					return;
				}

				try {
					jsonData = new JSONObject(result);
					
					if (mCallBackActivity == MainActivity.LOGIN_ACTIVITY) {		// There probably is a more elegant way to write this..
						if (requestType == MainActivity.requestType.CREATE_SESSION)
							LoginActivity.mServerHandler.sendEmptyMessage(2);
						else if (requestType == MainActivity.requestType.JOIN_SESSION)
							LoginActivity.mServerHandler.sendEmptyMessage(3);
					} else {
						if (requestType == MainActivity.requestType.UPDATE_SONG)
							MainActivity.mServerHandler.sendEmptyMessage(4);
						else if (requestType == MainActivity.requestType.UPDATE_FEED)
							MainActivity.mServerHandler.sendEmptyMessage(5);
						else if (requestType == MainActivity.requestType.FETCH_FEED)
							MainActivity.mServerHandler.sendEmptyMessage(6);
						else if (requestType == MainActivity.requestType.USER_LOG_OUT)
							MainActivity.mServerHandler.sendEmptyMessage(7);
						else if (requestType == MainActivity.requestType.KILL_SESSION)
							MainActivity.mServerHandler.sendEmptyMessage(8);
					}
				} catch(JSONException e){
					Log.e("myApp", "Error parsing data "+e.toString());
					if (mCallBackActivity == MainActivity.LOGIN_ACTIVITY) 
						LoginActivity.mServerHandler.sendEmptyMessage(1);
					else
						MainActivity.mServerHandler.sendEmptyMessage(1);
				}
			}        		
		}).start();
	}
    
	// TODO - Need to figure out which IP and how to return
	private static String getLocalIpAddress() {
	    try {
	        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
	            NetworkInterface intf = en.nextElement();
	            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
	                InetAddress inetAddress = enumIpAddr.nextElement();
	                Log.i("myApp", "IP Data Fetched: " + inetAddress);
	                if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
	                    return inetAddress.getHostAddress();
                  }
	            }
	        }
	    } catch (SocketException ex) {
	        ex.printStackTrace();
	    }
	    return null;
	}
}
